package com.lej.core.widget.scrollNum

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.util.AttributeSet
import android.view.View

class SingleScrollNumberView @JvmOverloads constructor(
    context: Context?,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
    private var mNumber = 0
    private var mTextColor = Color.BLACK
    private var mTextSize = 48f

    private var mPaint: Paint
    private var mBounds = Rect()

    private val scale = 1.3f

    /**
     * 由于只想用一个view完事，但是文字绘制的时候，不带边距，只好在measure的时候，用大字体占个大位置。在onDraw的时候，用小字体。这样文字就自带了边距
     */
    private var textOutHeight = 0
    private var textOutWidth = 0
    private var textInnerWidth = 0
    private var scrollY_ = 0

    fun setText(text: Char): SingleScrollNumberView {
        val num = text - '0'
        if (num in 0..9) {
            mNumber = num
        }
        return this
    }

    fun setTextColor(textColor: Int): SingleScrollNumberView {
        mTextColor = textColor
        mPaint.color = mTextColor
        return this
    }

    fun setTextSize(textSize: Float): SingleScrollNumberView {
        mTextSize = textSize
        mPaint.textSize = mTextSize * scale
        return this
    }

    fun setTextPadding(padding: Int): SingleScrollNumberView {
        textInnerWidth = padding
        return this
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val widthMode = MeasureSpec.getMode(widthMeasureSpec)
        val heightMode = MeasureSpec.getMode(heightMeasureSpec)
        var width = MeasureSpec.getSize(widthMeasureSpec)
        var height = MeasureSpec.getSize(heightMeasureSpec)
        if (widthMode == MeasureSpec.AT_MOST) {
            mPaint.getTextBounds(mNumber.toString(), 0, 1, mBounds)
            textOutWidth = mBounds.width()
            width = mBounds.width() + paddingLeft + paddingRight
        }
        if (heightMode == MeasureSpec.AT_MOST) {
            mPaint.getTextBounds(mNumber.toString(), 0, 1, mBounds)
            textOutHeight = mBounds.height()
            height = textOutHeight + paddingTop + paddingBottom
        }
        //设置宽高
        setMeasuredDimension(width, height)
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        //保持垂直方向居中
        //getPaddingLeft() + (textOutWidth - textInnerWidth) / 2 保持水平方向居中
        mPaint.textSize = mTextSize
        val fontMetrics = mPaint.fontMetricsInt
        val dy = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom
        val baseLine = height / 2 + dy
        for (i in 0..mNumber) {
            mPaint.textSize = mTextSize
            mPaint.getTextBounds(mNumber.toString(), 0, 1, mBounds)
            textInnerWidth = mBounds.width()
            canvas.drawText(
                i.toString(),
                (paddingLeft + (textOutWidth - textInnerWidth) / 2).toFloat(),
                (baseLine + i * textOutHeight - scrollY_).toFloat(),
                mPaint
            )
        }
    }

    private fun animateView() {
        postDelayed({
            if (!isAttachedToWindow) return@postDelayed
            //最大数字出现后，就要停下来。还要停稳，不然多几个数字，就会出现高低不平了。
            if (scrollY_ >= textOutHeight * mNumber) {
                scrollY_ = textOutHeight * mNumber
                postInvalidate()
                return@postDelayed
            }
            scrollY_ += textOutHeight / 4
            postInvalidate()
            animateView()
        }, 40)
    }

    fun start() {
        scrollY_ = 0
        animateView()
    }

    init {
        mPaint = Paint().apply {
            //设置抗锯齿
            isAntiAlias = true
            //设置字体和颜色
            textSize = mTextSize * scale
            color = mTextColor
        }
    }
}